<?php
App::uses ( 'CssMin', 'Lib' );
App::uses ( 'JSMin', 'Lib' );
App::uses ( 'Packer', 'Lib' );

/**
 * 将css,js文件汇总到一个文件输出,只支持数组方式传入参数,文件后缀名不能省略
 *
 * echo $this->Combinator->css(array(...)); 
 * // Output Javascript files. like $this->Html->css()
 * 
 * echo $this->Combinator->script(array(...)); 
 * // Output CSS files. like $this->Html->script()
 *
 * @author arlonzou
 *         @2012-9-11下午5:00:37
 */
App::import('Vendor', 'lessc', array('file' => 'lessphp'.DS.'lessc.inc.php'));
class CombinatorHelper extends Helper {
	
	public $helpers = array('Html','RequestHandler');
	
	function css($url,$compress = true) {
		return $this->get_css($url,$compress);
	}
	
	function script($url,$compress = true) {
			return $this->get_js($url,$compress);			
	}
	
	function less($styleid = ''){

		if(!Configure::read('Style.cssless') ){
			return $this->Html->css('bootstrap.min.css');
		}
    
		if(isset($_GET['styleid'])){
			$styleid = intval($_GET['styleid']);
		}
		
		if(empty($styleid)){
			if(defined('IS_MOBILE')){
				$styleid = Configure::read('Site.mobile_style');
			}
			else{
				$styleid = Configure::read('Site.style');
			}
		}
		$cachefile = 'bootstrap_'.$styleid.'.css';
		if(!file_exists( WEB_VISIT_CACHE .$cachefile )){
			
			$Style = loadModelObject('Style');
			$style_info = $Style->find('first',array('conditions'=>array('id'=>$styleid)));
			
			$css = '';
			
			$Stylevar = loadModelObject('Stylevar');
			$stylevars = $Stylevar->find('all',array('conditions'=>array('styleid'=>$styleid)));
			if(count($stylevars)>20){
				$variables = array();
				foreach($stylevars as $var){
					$variables[$var['Stylevar']['skey']] = $var['Stylevar']['sval'];
				}
				$less = new lessc;
				$less->setFormatter("compressed");//lessjs compressed classic
				$less->setImportDir(array(ROOT.'/data/less/'));
				$less->setVariables($variables);
				// 需要去掉bootstrap.less文件中包含的variable.less
				$css = $less->compileFile(ROOT.'/data/less/miaocms.less');
			}
			$css .= $style_info['Style']['css_content'];
			//$css = preg_replace('/url\(["|\']?(.+?)["|\']?\)/ies',"'url('.\$this->fixurl('\\1').')'",$css);
			file_put_contents(WEB_VISIT_CACHE.$cachefile, $css);
		}
		return '<link href="' .WEB_VISIT_CACHE_URL. $cachefile . '" rel="stylesheet" type="text/css" >';
	}
	
	private function get_js($url,$compress = true) {
	    
	    /**
	     * 不用version参数生成缓存名，发布时所有文件缓存都失效了。多机部署时，无法自动更新。CDN取不到对应的文件，缓存了空内容
	     */
	    
	    if( $GLOBALS['sys_version'] ) {
	        $cachefile = substr(md5( implode('_',$url) ),0,10).'-v'.$GLOBALS['sys_version'].'.js';
	    }
	    else{
	        $cachefile = substr(md5(implode('_',$url)),0,10).'.js';
	    }
	    
		if ( file_exists ( WEB_VISIT_CACHE .$cachefile ) && php_sapi_name() !=='cli' ) {
		    if( !Configure::read('debug') ) {
		        return '<script src="' . WEB_VISIT_CACHE_URL . $cachefile . '" type="text/javascript"></script>';
		    }
			else{
			    return '<script src="/cache/' . $cachefile . '" type="text/javascript"></script>';
			}
		}
		else{
		    if( !is_writable(WEB_VISIT_CACHE) && !defined('IN_SAE')  ) {
		        echo "webroot cache folder is not writable. ";
		        exit;
		    }
			//Get the content
			$has_min = false;
			$file_content = '';
			foreach ($url as $file ) {
				if(substr($file,0,1)=='/'){
					$path = WWW_ROOT.$file; //WWW_ROOT目录下的文件
				}
				else{
					$path = JS.$file; // js目录下的文件
				}
				
				$content = file_get_contents ( $path );
				if(strpos($path,'.min.')===false && $compress){ //参照指明不压缩时（$compress=false），跳过不压缩
// 						$packer = new Packer($content, 'None', true, true,false); // Packer错误，common.js  $(this).attr("target") == "_blank" 后面的_blank变成了_1
// 						$content = $packer->pack(); // packer js
					$content =  JSMin::minify ( $content ) ;// compress js !
				}
				else{
				    $has_min = true;
				}
				$file_content .= ";\n" .$content ;/*".basename($path)."*/
			}
			$file_content = trim ($file_content);
			
			$ret = file_put_contents(WEB_VISIT_CACHE.$cachefile, $file_content);
			if( !$has_min && $compress ) {
			    exec('uglifyjs '.WEB_VISIT_CACHE.$cachefile.' -o '.WEB_VISIT_CACHE.$cachefile.' -c -m');
			}
			
// 				var_dump($ret);
// 				App::uses ( 'File', 'Utility' );
// 				$file = new File(WEB_VISIT_CACHE.$cachefile);
// 				$file->open('w');
// 				$file->write($file_content);
// 				$file->close();
			if( !Configure::read('debug') ){
				return '<script src="' .WEB_VISIT_CACHE_URL.$cachefile . '" type="text/javascript"></script>';
			}
			else{
			    return '<script src="/cache/' . $cachefile . '" type="text/javascript"></script>';
			}
		}	
	}
	
	private function get_css($url,$compress = true) {
	    if($GLOBALS['sys_version']) {
	        $cachefile = substr(md5( $GLOBALS['sys_version'].'_'.implode('_',$url) ),0,10).'-v'.$GLOBALS['sys_version'].'.css';
	    }
	    else{
	        $cachefile = substr(md5(implode('_',$url)),0,10).'.css';
	    }
		
	    if ( file_exists ( WEB_VISIT_CACHE .$cachefile ) && php_sapi_name() !=='cli' ) {
	        if(!Configure::read('debug')) {
	            return '<link href="' .WEB_VISIT_CACHE_URL. $cachefile . '" rel="stylesheet" type="text/css" >';
	        }
	        else{
	            return '<link href="/cache/' . $cachefile . '" rel="stylesheet" type="text/css" >';
	        }
	    }
		
		if( !is_writable(WEB_VISIT_CACHE) && !defined('IN_SAE')  ) {
		    echo "webroot cache folder is not writable. ";
		    exit;
		}
		
		$file_content = '';
		foreach ($url as $file ) {
			if(substr($file,0,1)=='/'){
				$path = WWW_ROOT.$file;
			}
			else{
				$path = CSS.$file;
			}
			$content = file_get_contents ( $path );
			//url(../../img/desktop/gui/bar_top_link.png)
			$cur = str_replace('\\','\\\\',dirname($path)); // 转义路径中的反斜线，防止目录名含数字，如\3在正则中消失
			//$content = preg_replace('/url\(["|\']?(.+?)["|\']?\)/ies',"'url('.\$this->fixurl('\\1','$cur').')'",$content);
			
			$this->path = $cur;
			$content = preg_replace_callback('/url\(["|\']?(.+?)["|\']?\)/is', array($this,'fixurl'), $content);
			
			if(strpos($path,'.min.')===false && $compress){ //参照指明不压缩时（$compress=false），跳过不压缩
			    $content =  CssMin::minify( $content );// compress js !
			}
			
			// $content = ... ;//处理图片的相对路径
			$file_content .= "\n\n".$content;
		}
			
		$ret = file_put_contents(WEB_VISIT_CACHE.$cachefile, $file_content);
// 			App::uses ( 'File', 'Utility' );
// 			$file = new File(WEB_VISIT_CACHE.$cachefile);
// 			$file->open('w');
// 			$file->write($file_content);
// 			$file->close();
		if( !Configure::read('debug') ){
			return '<link href="' .WEB_VISIT_CACHE_URL.$cachefile . '"  rel="stylesheet" type="text/css" />';
		}
		else{
		    return '<link href="/cache/' . $cachefile . '" rel="stylesheet" type="text/css" >';
		}
	}
	
	private $path;
	
	private function fixurl($matches){
		
		$url = $matches[1];
		$path = $this->path;
	    
	    if(strpos($url,'http://') !== false) { //网址的路径直接跳过
	        return $matches[0];
	    }
	    
		if(substr($url,0,4)=='/img'){ // 已/img 开头，IMAGES_URL计算img所在的二级目录，img的二级目录和程序的二级目录不一样。如manage何img共用一个img目录
			$newurl =  str_replace('//','/',dirname(IMAGES_URL).$url);
			return 'url('.$newurl.')';
		}
		while(substr($url,0,3)=='../'){
			$path = dirname($path);
			$url = substr($url,3);
			if($path.DS == WWW_ROOT){
				$newurl = str_replace('//','/',dirname(IMAGES_URL).'/'.$url); 
				return 'url('.$newurl.')';
			}
		}
		$path = str_replace(WWW_ROOT, '', $path);
		$path = str_replace(array('\\','//'), '/', $path);
		$url = dirname(CSS_URL).'/'.$path.'/'.$url;
		$url = str_replace(array('\\/','//'),'/',$url); // css的相对路径，计算CSS_URL所在的二级目录
		return 'url('.$url.')';
	}
}